package org.chen.gateway.exception;

import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;

/**
 * 业务异常类
 */
@Data
@EqualsAndHashCode(callSuper = true)
public class BusinessException extends RuntimeException {

    /**
     * 错误码
     */
    private int code;

    /**
     * 错误信息
     */
    private String message;

    /**
     * 详细错误信息
     */
    private String detailMessage;

    public BusinessException() {
        super();
    }

    public BusinessException(String message) {
        super(message);
        this.code = 500;
        this.message = message;
    }

    public BusinessException(int code, String message) {
        super(message);
        this.code = code;
        this.message = message;
    }

    public BusinessException(String message, Throwable cause) {
        super(message, cause);
        this.code = 500;
        this.message = message;
        this.detailMessage = cause.getMessage();
    }

    public BusinessException(int code, String message, Throwable cause) {
        super(message, cause);
        this.code = code;
        this.message = message;
        this.detailMessage = cause.getMessage();
    }

    public BusinessException(ResultCode resultCode) {
        super(resultCode.getMessage());
        this.code = resultCode.getCode();
        this.message = resultCode.getMessage();
    }

    public BusinessException(ResultCode resultCode, Throwable cause) {
        super(resultCode.getMessage(), cause);
        this.code = resultCode.getCode();
        this.message = resultCode.getMessage();
        this.detailMessage = cause.getMessage();
    }

    public BusinessException(ResultCode resultCode, String customMessage) {
        super(customMessage);
        this.code = resultCode.getCode();
        this.message = customMessage;
    }

    /**
     * 常用的业务异常创建方法
     */
    public static BusinessException of(String message) {
        return new BusinessException(message);
    }

    public static BusinessException of(int code, String message) {
        return new BusinessException(code, message);
    }

    public static BusinessException of(ResultCode resultCode) {
        return new BusinessException(resultCode);
    }

    public static BusinessException of(ResultCode resultCode, String customMessage) {
        return new BusinessException(resultCode, customMessage);
    }

    /**
     * 参数验证异常
     */
    public static BusinessException paramError(String message) {
        return new BusinessException(400, message);
    }

    /**
     * 未授权异常
     */
    public static BusinessException unauthorized(String message) {
        return new BusinessException(401, message);
    }

    /**
     * 禁止访问异常
     */
    public static BusinessException forbidden(String message) {
        return new BusinessException(403, message);
    }

    /**
     * 资源不存在异常
     */
    public static BusinessException notFound(String message) {
        return new BusinessException(404, message);
    }

    /**
     * 服务器内部错误异常
     */
    public static BusinessException serverError(String message) {
        return new BusinessException(500, message);
    }
}

/**
 * 结果码枚举
 */
@Getter
enum ResultCode {

    SUCCESS(200, "操作成功"),

    // 客户端错误 4xx
    BAD_REQUEST(400, "请求参数错误"),
    UNAUTHORIZED(401, "未授权"),
    FORBIDDEN(403, "禁止访问"),
    NOT_FOUND(404, "资源不存在"),
    METHOD_NOT_ALLOWED(405, "请求方法不允许"),
    CONFLICT(409, "资源冲突"),
    UNSUPPORTED_MEDIA_TYPE(415, "不支持的媒体类型"),

    // 服务器错误 5xx
    INTERNAL_SERVER_ERROR(500, "服务器内部错误"),
    NOT_IMPLEMENTED(501, "功能未实现"),
    BAD_GATEWAY(502, "网关错误"),
    SERVICE_UNAVAILABLE(503, "服务不可用"),
    GATEWAY_TIMEOUT(504, "网关超时"),

    // 业务错误 1xxx
    USER_NOT_FOUND(1001, "用户不存在"),
    USER_ALREADY_EXISTS(1002, "用户已存在"),
    INVALID_PASSWORD(1003, "密码错误"),
    ACCOUNT_LOCKED(1004, "账户已锁定"),
    ACCOUNT_DISABLED(1005, "账户已禁用"),
    PASSWORD_EXPIRED(1006, "密码已过期"),

    // 认证错误 2xxx
    TOKEN_INVALID(2001, "无效的令牌"),
    TOKEN_EXPIRED(2002, "令牌已过期"),
    TOKEN_MISSING(2003, "缺少令牌"),
    LOGIN_FAILED(2004, "登录失败"),
    LOGOUT_FAILED(2005, "登出失败"),

    // 权限错误 3xxx
    PERMISSION_DENIED(3001, "权限不足"),
    ROLE_NOT_FOUND(3002, "角色不存在"),
    PERMISSION_NOT_FOUND(3003, "权限不存在"),

    // 数据错误 4xxx
    DATA_NOT_FOUND(4001, "数据不存在"),
    DATA_ALREADY_EXISTS(4002, "数据已存在"),
    DATA_VALIDATION_FAILED(4003, "数据验证失败"),
    DATA_CONSTRAINT_VIOLATION(4004, "数据约束违反"),

    // 文件错误 5xxx
    FILE_NOT_FOUND(5001, "文件不存在"),
    FILE_UPLOAD_FAILED(5002, "文件上传失败"),
    FILE_DOWNLOAD_FAILED(5003, "文件下载失败"),
    FILE_SIZE_EXCEEDED(5004, "文件大小超限"),
    FILE_TYPE_NOT_SUPPORTED(5005, "不支持的文件类型"),

    // 外部服务错误 6xxx
    EXTERNAL_SERVICE_ERROR(6001, "外部服务错误"),
    NETWORK_ERROR(6002, "网络错误"),
    TIMEOUT_ERROR(6003, "请求超时");

    private final int code;
    private final String message;

    ResultCode(int code, String message) {
        this.code = code;
        this.message = message;
    }

}